package com.example.controller.pc;

import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.common.result.Result;
import com.example.entity.mysql.Resourcegroup;
import com.example.entity.mysql.Scheduleconfig;
import com.example.entity.vo.pc.*;
import com.example.entity.yifei.Cmsma;
import com.example.entity.yifei.Cmsmq;
import com.example.entity.yifei.Invmc;
import com.example.entity.yifei.Moctb;
import com.example.entity.ymlConfig.YmlConfig;
import com.example.exception.CustomException;
import com.example.mapper.DbtempMapper;
import com.example.mapper.MoctbMapper;
import com.example.mapper.MoctcMapper;
import com.example.mapper.pc.LingLiaoMapper;
import com.example.service.*;
import com.example.service.pc.LingLiaoService;
import com.example.untils.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@RestController
@RequestMapping("/api/lingLiao")
@Api(tags = "领料")
public class LingLiaoController {

    @Autowired
    private LingLiaoService lingLiaoService;

    @Autowired
    private LingLiaoMapper lingLiaoMapper;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private DbtempService dbtempService;

    @Autowired
    private DbtempMapper dbtempMapper;

    @Autowired
    private MoctcMapper moctcMapper;

    @Autowired
    private InvmcService invmcService;

    @Autowired
    private MoctbMapper moctbMapper;

    @Autowired
    private CmsmqService cmsmqService;

    @Autowired
    private CmsmaService cmsmaService;

    @Autowired
    private MoctaService moctaService;

    @Autowired
    private MocteService mocteService;

    @Autowired
    private InvmbService invmbService;

    @Autowired
    private ScheduleconfigService scheduleconfigService;

    @ApiOperation("查看系统设置，小数点后几位")
    @PostMapping("selWS")
    public Result<Integer> selWS() {
        Cmsma cmsma = cmsmaService.getOne(new LambdaQueryWrapper<Cmsma>().eq(Cmsma::getCompany, YmlConfig.getYFCOMPANY()));
        return Result.success(Integer.parseInt(cmsma.getMa068()));
    }

    @ApiOperation("领/退/补料单列表")
    @PostMapping("LTLDlist")
    public Result<List<Cmsmq>> LTLDlist() {
        return Result.success(cmsmqService.list(new LambdaQueryWrapper<Cmsmq>().between(Cmsmq::getMq003, "54", "57")));
    }

    @ApiOperation("领料单列表")
    @PostMapping("LLDlist")
    public Result<List<Cmsmq>> LLDlist() {
        return Result.success(cmsmqService.list(new LambdaQueryWrapper<Cmsmq>().eq(Cmsmq::getMq003, "54")));
    }

    @ApiOperation("退料单列表")
    @PostMapping("TLDlist")
    public Result<List<Cmsmq>> TLDlist() {
        return Result.success(cmsmqService.list(new LambdaQueryWrapper<Cmsmq>().eq(Cmsmq::getMq003, "56")));
    }

    @ApiOperation("补退料单列表")
    @PostMapping("BTLDlist")
    public Result<List<Cmsmq>> BTLDlist() {
        return Result.success(cmsmqService.list(new LambdaQueryWrapper<Cmsmq>().eq(Cmsmq::getMq001, "AMB1").or().eq(Cmsmq::getMq001, "AMB2").or().eq(Cmsmq::getMq001, "AMR1").or().eq(Cmsmq::getMq001, "AMR2")));
    }

    @ApiOperation("列表")
    @PostMapping("list")
    public Result<List<LingLiaoListVo>> list(@RequestBody LingLiaoListDto dto) {
        List<LingLiaoListVo> list = null;
        if(dto.getCheckbox1()) {  // 如果选择了 [不根据排产计划领料]
            list = lingLiaoMapper.listCheckBox1(dto);
        }else{
            list = lingLiaoMapper.listUnCheckBox1(dto);
            Set<String> idSet = new HashSet<>();
            for(LingLiaoListVo t : list) {
                if(t.getLineType().trim().equals("") || t.getLineType().trim().equals("****")) continue;
                idSet.add(t.getLineType().trim());
            }
            List<String> ids = new ArrayList<>();
            for(String str : idSet) ids.add(str);
            if(ids.size() > 0) {
                List<Resourcegroup> resourcegroupList = lingLiaoMapper.getIdNameList(ids);
                Map<Integer, String> map = new HashMap<>();
                for(Resourcegroup t : resourcegroupList) {
                    map.put(t.getResourceGroupId(), t.getResourceGroupName());
                }
                for(LingLiaoListVo t : list) {
                    if(t.getLineType().trim().equals("") || t.getLineType().trim().equals("****")) continue;
                    t.setLineType(map.get(Integer.parseInt(t.getLineType().trim())));
                }
            }
        }
        return Result.success(list);
    }

    @ApiOperation("自动生成领料单")
    @PostMapping("autoGenLL")
    @DSTransactional
    public Result autoGenLL(@RequestBody AutoGenLLDto dto) {
        if(StringUtils.isEmpty(dto.getLlDate())) {
            throw new CustomException("500", "单据开立日期为空!");
        }
//        dto.setMoctaMerge(true);
        if(StringUtils.isEmpty(dto.getCurUser())) {
            throw new CustomException("500", "没有传入当前登录用户!");
        }
        String wwGDdb = "AMM2";   // 委外工单单别
        String zzGDdb = "AMM1";  // 自制工单单别

        String wwdb = "AMU2";   //  委外领料单别
        String zzdb = "AMU1";   //  自制领料单别
//        dto.setLlType("AMU1");
//        String username = SecurityUtils.getLoginUser().getUsername();
//        if(username == null) {
//            throw new CustomException("500", "没有登录!");
//        }
        for(AutoGenLL t : dto.getCheckedlist()) {
            if(t.getLlCode().trim().equals("Y")) {
                throw new CustomException("500", t.getType() + "-" + t.getId() + "已经领过料的任务单不能按此按钮产生领料单，请按生成补料单!");
            }
        }
        Scheduleconfig scheduleconfig = scheduleconfigService.getOne(new LambdaQueryWrapper<Scheduleconfig>().eq(Scheduleconfig::getCompany, YmlConfig.getYFCOMPANY()));
        Integer pickDivide = scheduleconfig.getPickDivide();
        Integer moctaMerge = scheduleconfig.getMoctaMerge();

        List<Cmsmq> moctaList = cmsmqService.list(new LambdaQueryWrapper<Cmsmq>().eq(Cmsmq::getMq003, "51").or().eq(Cmsmq::getMq003, "52"));
        Set<String> zzGDSet = new HashSet<>();  Set<String> wwGDSet = new HashSet<>();
        for(Cmsmq cmsmq : moctaList) {
            if("1".equals(cmsmq.getMq030().trim())) {
                zzGDSet.add(cmsmq.getMq001().trim());
            }else if("2".equals(cmsmq.getMq030().trim())) {
                wwGDSet.add(cmsmq.getMq001().trim());
            }
        }
//        Cmsma cmsma = cmsmaService.getOne(new LambdaQueryWrapper<Cmsma>().eq(Cmsma::getCompany, "ZJHZ"));
//        StringBuffer sb = new StringBuffer();
        List<AutoGenLL> list = dto.getCheckedlist();
        List<AutoGenLL> zzList = new ArrayList<>();  // 自制工单
        List<AutoGenLL> wwList = new ArrayList<>();  // 委外工单
        if(pickDivide == null || pickDivide.equals(1)) {
            for(AutoGenLL a : list) {
                if(wwGDSet.contains(a.getType().trim())) {  // 委外单别
                    wwList.add(a);
                }else if(zzGDSet.contains(a.getType().trim())) {
                    zzList.add(a);
                }
//                if(a.getType().trim().equals(wwGDdb)) {  // 委外单别
//                    wwList.add(a);
//                }else if(zzGDdb.equals(a.getType().trim())){
//                    zzList.add(a);
//                }
            }
        }else if(pickDivide.equals(2)) {
            for(AutoGenLL a : list) {
                if("2".equals(a.getMoctaType().trim())) {  // 委外单别
                    wwList.add(a);
                }else if("1".equals(a.getMoctaType().trim())){
                    zzList.add(a);
                }
            }
        }else{
            throw new CustomException("500", "领料时系统区分工单异常!");
        }

        // 检查工单的工作中心是否一样，或者是否为空
        for(int i = 0; i < zzList.size(); i++) {
            if(StringUtils.isEmpty(zzList.get(i).getWorkCenterId())) throw new CustomException("500", "工单：" + zzList.get(i).getType() + "-" + zzList.get(i).getId() + "没有工作中心!");
            if(!zzList.get(0).getWorkCenterId().trim().equals(zzList.get(i).getWorkCenterId().trim())) {
                throw new CustomException("500", "领料时工单工作中心需要一致!");
            }
        }
        // 检查工单的委外供应商是否一样，或者是否为空
        for(int i = 0; i < wwList.size(); i++) {
            if(StringUtils.isEmpty(wwList.get(i).getSupplierId())) throw new CustomException("500", "工单：" + wwList.get(i).getType() + "-" + wwList.get(i).getId() + "没有委外供应商!");
            if(!wwList.get(0).getSupplierId().trim().equals(wwList.get(i).getSupplierId().trim())) {
                throw new CustomException("500", "领料时委外供应商需要一致!");
            }
        }

        String res = "";
        if(dto.getCheckbox1()) {  // 按工单
            if(moctaMerge == null || moctaMerge.equals(1)) {   // 工单合并为一张领料单领料
                for(AutoGenLL t : zzList) {
                    lingLiaoMapper.updateTa016(t.getType(), t.getId());
                }
                if(zzList.size() > 0) res += lingLiaoService.gongdanAutoLL(zzList, zzdb, "54", true, dto.getLlDate());

                for(AutoGenLL t : wwList) {
                    lingLiaoMapper.updateTa016(t.getType(), t.getId());
                }
                if(wwList.size() > 0) res += lingLiaoService.gongdanAutoLL(wwList, wwdb, "55", true, dto.getLlDate());
            }else if(moctaMerge.equals(0)){
                for(AutoGenLL t : zzList) {
                    lingLiaoMapper.updateTa016(t.getType(), t.getId());
                    res += lingLiaoService.gongdanAutoLL(zzList, zzdb, "54", true, dto.getLlDate());
                }
                for(AutoGenLL t : wwList) {
                    lingLiaoMapper.updateTa016(t.getType(), t.getId());
                    res += lingLiaoService.gongdanAutoLL(wwList, wwdb, "55", true, dto.getLlDate());
                }
            }
        }else{    // 按排产
            // TODO 目前不正确，工序级的排产，是错的  如果是工序级，似乎无法追踪
            if(moctaMerge == null || moctaMerge.equals(1)) {  // 工单合并为一张领料单领料
                for(AutoGenLL t : zzList) {
                    lingLiaoMapper.updateMoctyTy018(t.getUuid());
                }
                if(zzList.size() > 0) res += lingLiaoService.gongdanAutoLL(zzList, zzdb, "54", false, dto.getLlDate());

                for(AutoGenLL t : wwList) {
                    lingLiaoMapper.updateMoctyTy018(t.getUuid());
                }
                if(wwList.size() > 0) res += lingLiaoService.gongdanAutoLL(wwList, wwdb, "55", false, dto.getLlDate());
            }else if(moctaMerge.equals(0)) {
                for(AutoGenLL t : zzList) {
                    lingLiaoMapper.updateMoctyTy018(t.getUuid());
                    res += lingLiaoService.gongdanAutoLL(zzList, zzdb, "54", false, dto.getLlDate());
                }
                for(AutoGenLL t : wwList) {
                    lingLiaoMapper.updateMoctyTy018(t.getUuid());
                    res += lingLiaoService.gongdanAutoLL(wwList, wwdb, "55", false, dto.getLlDate());
                }
            }
        }
        return Result.success("领料成功。\n" + res);
    }

    @ApiOperation("其他品号查询")
    @PostMapping("otherProductSelect")
    public Result<PageInfo<OtherProductSelectVo>> otherProductSelect(@RequestBody OtherProductSelectDto dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        List<OtherProductSelectVo> list = lingLiaoMapper.otherProductSelect(dto);
        for(OtherProductSelectVo t : list) {
//            t.setType(dto.getType());  t.setId(dto.getId());
            t.setUuid(UUID.randomUUID().toString());
        }
        PageInfo<OtherProductSelectVo> pageInfo = new PageInfo(list);
        return Result.success(pageInfo);
    }

    @ApiOperation("点击选择框之后")
    @PostMapping("afterClickCheckBox")
    public Result<List<OtherProductSelectVo>> afterClickCheckBox(@RequestBody AfterClickCheckBoxDto dto) {
        List<OtherProductSelectVo> list = lingLiaoMapper.afterClickCheckBoxWith2(dto);
        for(OtherProductSelectVo t : list) {
            BigDecimal sysl = t.getReqNums().subtract(t.getTB005()).subtract(t.getTE005());  // 剩余未领数量
            if(sysl.compareTo(new BigDecimal(0D)) < 0) sysl = new BigDecimal(0D);
            BigDecimal bcll = null;  // 本次领料数量
            if(t.getTA015().equals(new BigDecimal(0))) bcll = new BigDecimal(0);
            else bcll = dto.getNums().divide(t.getTA015(), 8, RoundingMode.HALF_UP).multiply(t.getReqNums());
            if(bcll.compareTo(sysl) > 0) bcll = sysl;
            Cmsma cmsma = cmsmaService.getOne(new LambdaQueryWrapper<Cmsma>().eq(Cmsma::getCompany, YmlConfig.getYFCOMPANY()));
            t.setUnReceivedNums(bcll.setScale(Integer.parseInt(cmsma.getMa068()), RoundingMode.HALF_UP));
            t.setUuid(UUID.randomUUID().toString());
            t.setWorkCenterId(dto.getWorkCenterId());
            t.setMoctaType(dto.getMoctaType());
            t.setSupplierId(dto.getSupplierId());
        }
        return Result.success(list);
    }

    @ApiOperation("生成补/退料单")
    @PostMapping("autoBTdan")
    @DSTransactional
    public Result autoBTdan(@RequestBody AutoBTdanDto dto) {
        if(StringUtils.isEmpty(dto.getLlDate())) {
            throw new CustomException("500", "单据开立日期为空!");
        }
//        if(StringUtils.isEmpty(dto.getWorkCenter())) {
//            throw new CustomException("500", "工作中心不可为空!");
//        }
        Scheduleconfig scheduleconfig = scheduleconfigService.getOne(new LambdaQueryWrapper<Scheduleconfig>().eq(Scheduleconfig::getCompany, "ZJHZ"));
        Integer pickDivide = scheduleconfig.getPickDivide();
        Integer moctaMerge = scheduleconfig.getMoctaMerge();

        List<Cmsmq> moctaList = cmsmqService.list(new LambdaQueryWrapper<Cmsmq>().eq(Cmsmq::getMq003, "51").or().eq(Cmsmq::getMq003, "52"));
        Set<String> zzGDSet = new HashSet<>();  Set<String> wwGDSet = new HashSet<>();
        for(Cmsmq cmsmq : moctaList) {
            if("1".equals(cmsmq.getMq030().trim())) {
                zzGDSet.add(cmsmq.getMq001().trim());
            }else if("2".equals(cmsmq.getMq030().trim())) {
                wwGDSet.add(cmsmq.getMq001().trim());
            }
        }
        // 委外单别，自制单别
//        String wwdb = "AMM2", zzdb = "AMM1";
        List<AutoBTdan> list = dto.getCheckedList();
        List<AutoBTdan> wwList = new ArrayList<>();
        List<AutoBTdan> zzList = new ArrayList<>();
        String res = "";
        // 先区分出委外工单，自制工单
        if(pickDivide == null || pickDivide.equals(1)) {
            for(AutoBTdan a : list) {
                if(wwGDSet.contains(a.getType().trim())) {  // 委外单别
                    wwList.add(a);
                }else if(zzGDSet.contains(a.getType().trim())) {
                    zzList.add(a);
                }
//                if(a.getType().trim().equals(wwdb)) {  // 委外单别
//                    wwList.add(a);
//                }else if(zzdb.equals(a.getType().trim())){
//                    zzList.add(a);
//                }
            }
        }else if(pickDivide.equals(2)) {
            for(AutoBTdan a : list) {
                if("2".equals(a.getMoctaType().trim())) {  // 委外单别
                    wwList.add(a);
                }else if("1".equals(a.getMoctaType().trim())){
                    zzList.add(a);
                }
            }
        }else{
            throw new CustomException("500", "领料时系统区分工单异常!");
        }

        // 检查工单的工作中心是否一样，或者是否为空
        for(int i = 0; i < zzList.size(); i++) {
            if(StringUtils.isEmpty(zzList.get(i).getWorkCenterId())) throw new CustomException("500", "工单：" + zzList.get(i).getType() + "-" + zzList.get(i).getId() + "没有工作中心!");
            if(!zzList.get(0).getWorkCenterId().trim().equals(zzList.get(i).getWorkCenterId().trim())) {
                throw new CustomException("500", "领料时工单工作中心需要一致!");
            }
        }
        // 检查工单的委外供应商是否一样，或者是否为空
        for(int i = 0; i < wwList.size(); i++) {
            if(StringUtils.isEmpty(wwList.get(i).getSupplierId())) throw new CustomException("500", "工单：" + wwList.get(i).getType() + "-" + wwList.get(i).getId() + "没有委外供应商!");
            if(!wwList.get(0).getSupplierId().trim().equals(wwList.get(i).getSupplierId().trim())) {
                throw new CustomException("500", "领料时委外供应商需要一致!");
            }
        }
//        for(AutoBTdan t : list) {
//            if(t.getType().trim().equals(wwdb)) {
//                wwList.add(t);
//            }else if(t.getType().trim().equals(zzdb)) {
//                zzList.add(t);
//            }else{
//                throw new CustomException("500", "不属于委外单别" + wwdb + "或自制单别" + zzdb + ",无法区分!");
//            }
//        }

        List<Cmsmq> cmsmqList = cmsmqService.list();
        Map<String, String> cmsmqMap = new HashMap<>();
        for(Cmsmq cmsmq : cmsmqList) {
            cmsmqMap.put(cmsmq.getMq001().trim(), cmsmq.getMq002().trim());
        }
        String zzLL = cmsmqMap.get("材料领料单");   String wwLL = cmsmqMap.get("委外领料单");
        String zzBL = cmsmqMap.get("材料补料单");   String wwBL = cmsmqMap.get("委外补料单");
        String zzTL = cmsmqMap.get("材料退料单");   String wwTL = cmsmqMap.get("委外退料单");

        dto.setTlType(wwTL);  dto.setLlType(dto.getIsLL() ? wwLL : wwBL);  dto.setCheckedList(wwList);
        res += lingLiaoService.autoBTdan(dto, false);

        dto.setTlType(zzTL);  dto.setLlType(dto.getIsLL() ? zzLL : zzBL);  dto.setCheckedList(zzList);
        res += lingLiaoService.autoBTdan(dto,true);
        return Result.success("生成成功。\n" + res);
    }

    @ApiOperation("领料查询 列表")
    @PostMapping("llList")
    public Result<List<LlListVo>> llList(@RequestBody LlListDto dto) {
        List<LlListVo> list = lingLiaoMapper.llList(dto);
        return Result.success(list);
    }

    @ApiOperation("删除")
    @DSTransactional
    @PostMapping("del/{type}/{id}/{no}/{auditCode}")
    public Result del(@PathVariable String type, @PathVariable String id,
                      @PathVariable String no, @PathVariable String auditCode) {
        if(auditCode.equals("Y")) {
            throw new CustomException("500", "已审核的单据不允许删除!");
        }
        moctcMapper.delMocte(type, id, no);
        moctcMapper.delMoctcNoMocte(type, id);
        return Result.success("删除成功!");
    }

    @ApiOperation("更改为不需要领料")
    @DSTransactional
    @PostMapping("updateToNotLL")
    public Result updateToNotLL(@RequestBody UpdateToNotLLDto dto) {
        Moctb moctb = moctbMapper.selectOne(new LambdaQueryWrapper<Moctb>().eq(Moctb::getTb001, dto.getType()).eq(Moctb::getTb002, dto.getId())
                .eq(Moctb::getTb003, dto.getProductId()).eq(Moctb::getTb006, dto.getProcess()));
        if(moctb == null) {
            throw new CustomException("500", "工单单身中不存在此品号!");
        }
        Moctb moctb1 = new Moctb(); moctb1.setTb004(moctb.getTb005()); moctb1.setTb027(moctb.getTb005());
        moctbMapper.update(moctb1, new LambdaQueryWrapper<Moctb>().eq(Moctb::getTb001, dto.getType()).eq(Moctb::getTb002, dto.getId())
                .eq(Moctb::getTb003, dto.getProductId()).eq(Moctb::getTb006, dto.getProcess()));
        return Result.success("更新成功!");
    }

    @ApiOperation("查询一个物料是否有可以替换的物料件")
    @PostMapping("replaceItemList/{yuanjian}/{zhujian}/{type}/{id}")
    public Result<List<OtherProductSelectVo>> replaceItemList(@PathVariable String yuanjian, @PathVariable String zhujian,
                                                              @PathVariable String type, @PathVariable String id) {
        List<OtherProductSelectVo> list = lingLiaoMapper.replaceItemList(yuanjian, zhujian);
        for(OtherProductSelectVo t : list) {
            t.setType(type);  t.setId(id);
        }
        return Result.success(list);
    }

    @ApiOperation("获得领料原因 1是获取领料原因，2是获取退料原因")
    @PostMapping("getLLReason/{type}")
    public Result<List> getLLReason(@PathVariable String type) {
        List<LLReasonVo> res = new ArrayList();
        if("1".equals(type)) {
            res.add(new LLReasonVo("补料原因_来料不良"));
            res.add(new LLReasonVo("补料原因_来料少"));
            res.add(new LLReasonVo("补料原因_来料报废"));
            res.add(new LLReasonVo("补料原因_备品"));
            res.add(new LLReasonVo("补料原因_制程不良"));
            res.add(new LLReasonVo("补料原因_制程报废"));
            res.add(new LLReasonVo("补料原因_遗失补料"));
        }else if("2".equals(type)){
            res.add(new LLReasonVo("退料原因_余料退回"));
            res.add(new LLReasonVo("退料原因_来料不良退回"));
        }
        return Result.success(res);
    }

    @ApiOperation("切换仓库")
    @PostMapping("changeStock/{productId}/{stockId}")
    public Result<BigDecimal> changeStock(@PathVariable String productId, @PathVariable String stockId) {
        Map<String, Object> res = new HashMap();
        Invmc one = invmcService.getOne(new LambdaQueryWrapper<Invmc>().eq(Invmc::getMC001, productId).eq(Invmc::getMC002, stockId));
        if(one == null) return Result.success(new BigDecimal(0D));
        BigDecimal nums = one.getMC007() == null ? new BigDecimal(0) : one.getMC007();
        return Result.success(nums);
    }

}